package com.mdd.front.service.order.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryV3Result;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.yulichang.query.MPJQueryWrapper;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.course.Course;
import com.mdd.common.entity.course.StudyCourse;
import com.mdd.common.entity.order.ConsumptionIncentives;
import com.mdd.common.entity.order.Order;
import com.mdd.common.entity.order.OrderCourse;
import com.mdd.common.entity.order.OrderLog;
import com.mdd.common.entity.system.Coupon;
import com.mdd.common.entity.system.CouponReceive;
import com.mdd.common.entity.system.SystemConfig;
import com.mdd.common.entity.teacher.Teacher;
import com.mdd.common.entity.user.PointsLog;
import com.mdd.common.entity.user.User;
import com.mdd.common.enums.ClientEnum;
import com.mdd.common.enums.OrderEnum;
import com.mdd.common.enums.OrderLogEnum;
import com.mdd.common.enums.PointsChangeEnum;
import com.mdd.common.mapper.course.CourseMapper;
import com.mdd.common.mapper.course.StudyCourseMapper;
import com.mdd.common.mapper.order.ConsumptionIncentivesMapper;
import com.mdd.common.mapper.order.OrderCourseMapper;
import com.mdd.common.mapper.order.OrderLogMapper;
import com.mdd.common.mapper.order.OrderMapper;
import com.mdd.common.mapper.system.CouponMapper;
import com.mdd.common.mapper.system.CouponReceiveMapper;
import com.mdd.common.mapper.system.SystemConfigMapper;
import com.mdd.common.mapper.user.PointsLogMapper;
import com.mdd.common.mapper.user.UserMapper;
import com.mdd.common.utils.*;
import com.mdd.front.LikeFrontThreadLocal;
import com.mdd.front.service.order.IOrderService;
import com.mdd.front.service.system.ISystemDevPayService;
import com.mdd.front.utils.WxPayServiceUtil;
import com.mdd.front.validate.OrderParam;
import com.mdd.front.validate.PageParam;
import com.mdd.front.vo.order.OrderDetailVo;
import com.mdd.front.vo.order.OrderListVo;
import com.mdd.front.vo.system.SystemDevWxPayConfig;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Time;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单实现类
 * @author panweiliang
 */
@Service
public class OrderServiceImpl implements IOrderService {

    final Logger log = LoggerFactory.getLogger(this.getClass());
        
    @Resource
    OrderMapper orderMapper;

    @Resource
    OrderCourseMapper orderCourseMapper;

    @Resource
    OrderLogMapper orderLogMapper;

    @Resource
    CourseMapper courseMapper;

    @Resource
    UserMapper userMapper;

    @Resource
    private CouponReceiveMapper couponReceiveMapper;

    @Resource
    private CouponMapper couponMapper;

    @Resource
    private StudyCourseMapper studyCourseMapper;

    @Resource
    private ConsumptionIncentivesMapper consumptionIncentivesMapper;

    @Resource
    private PointsLogMapper pointsLogMapper;


    /**
     * 订单列表
     *
     * @author panweiliang
     * @param pageParam 分页参数
     * @param params 搜索参数
     * @return PageResult<OrderListVo>
     */
    @Override
    public PageResult<OrderListVo> list(PageParam pageParam, Map<String, String> params) {
        String cancelUnpaidOrders = LsConfigUtil.get("transaction", "cancel_unpaid_orders");
        String cancelUnpaidOrdersTimesStr = LsConfigUtil.get("transaction", "cancel_unpaid_orders_times", "30");
        Integer page  = pageParam.getPageNo();
        Integer limit = pageParam.getPageSize();
        Integer userId = LikeFrontThreadLocal.getUserId();
        MPJQueryWrapper<Order> mpjQueryWrapper = new MPJQueryWrapper<Order>()
                .selectAll(Order.class)
                .select("oc.course_snap as courseSnap, course.name as courseName, course.cover as courseCover, course.sell_price as courseSellPrice, oc.is_comment AS commented ")
                .innerJoin("?_order_course oc ON oc.order_id=t.id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .innerJoin("?_course course ON course.id=oc.course_id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .eq("t.user_id", userId)
                .isNull("t.delete_time")
                .orderByDesc(Arrays.asList("t.id"));

        params.put("orderStatus", "null".equals(params.get("orderStatus")) ? "" : params.get("orderStatus"));

        orderMapper.setSearch(mpjQueryWrapper, params, new String[]{
                "=:orderStatus@t.order_status:int",
        });
        IPage<OrderListVo> iPage = orderMapper.selectJoinPage(new Page<>(page, limit), OrderListVo.class, mpjQueryWrapper);
        for(OrderListVo item : iPage.getRecords()) {
            Long createTime = Long.parseLong(item.getCreateTime());
            item.setCreateTime(TimeUtil.timestampToDate(createTime));
            item.setUpdateTime(TimeUtil.timestampToDate(item.getUpdateTime()));
            item.setCancelTime(TimeUtil.timestampToDate(item.getCancelTime()));
            item.setPayTime(TimeUtil.timestampToDate(item.getPayTime()));
            item.setRefundTime(TimeUtil.timestampToDate(item.getRefundTime()));
            item.setCourseCover(UrlUtil.toAbsoluteUrl(item.getCourseCover()));
            if ("1".equals(cancelUnpaidOrders)) {
                Long cancelUnpaidOrdersTimes = Long.parseLong(cancelUnpaidOrdersTimesStr);
                Long orderExpireTime = createTime * 1000 + cancelUnpaidOrdersTimes * 60 * 1000;
                item.setCancelUnpaidOrders(true);
                item.setOrderExpireTime(orderExpireTime);
            } else {
                item.setCancelUnpaidOrders(false);
                item.setOrderExpireTime(0l);
            }
            if (item.getOrderStatus().intValue() != OrderEnum.ORDER_STATUS_COMPLETED.getCode()) {
                item.setShowComment(false);
            } else if (item.getRefundStatus().intValue() != OrderEnum.REFUND_STATUS_NO.getCode()) {
                item.setShowComment(false);
            } else {
                item.setShowComment(!item.isCommented());
            }
        }
        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), iPage.getRecords());
    }


    /**
     * 订单详情
     *
     * @author panweiliang
     * @param id 主键参数
     * @return Order
     */
//    @Override
    public OrderDetailVo detail(Integer id, Integer userId) {
        String cancelUnpaidOrders = LsConfigUtil.get("transaction", "cancel_unpaid_orders");
        String cancelUnpaidOrdersTimesStr = LsConfigUtil.get("transaction", "cancel_unpaid_orders_times", "30");
        MPJQueryWrapper<Order> mpjQueryWrapper = new MPJQueryWrapper<Order>()
                .selectAll(Order.class)
                .select("oc.course_snap as courseSnap, course.name as courseName, course.cover as courseCover, course.sell_price as courseSellPrice, oc.is_comment AS commented ")
                .innerJoin("?_order_course oc ON oc.order_id=t.id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .innerJoin("?_course course ON course.id=oc.course_id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .eq("t.id", id)
                .eq("t.user_id", userId)
                .last("limit 1")
                .orderByDesc(Arrays.asList("t.id"));

        OrderDetailVo vo = orderMapper.selectJoinOne(OrderDetailVo.class, mpjQueryWrapper);
        Assert.notNull(vo, "数据不存在");

        String courseSnap = vo.getCourseSnap();
        if (StringUtil.isNotEmpty(courseSnap)) {
            JSONObject jsonObject = JSONObject.parseObject(courseSnap);
            jsonObject.put("cover", UrlUtil.toAbsoluteUrl(jsonObject.getString("cover")));
            courseSnap = jsonObject.toJSONString();
            vo.setCourseSnap(courseSnap);
        }

        Long createTime = Long.parseLong(vo.getCreateTime());
        vo.setCreateTime(TimeUtil.timestampToDate(vo.getCreateTime()));
        vo.setCancelTime(TimeUtil.timestampToDate(vo.getCancelTime()));
        vo.setPayTime(TimeUtil.timestampToDate(vo.getPayTime()));
        vo.setRefundTime(TimeUtil.timestampToDate(vo.getRefundTime()));
        vo.setCourseCover(UrlUtil.toAbsoluteUrl(vo.getCourseCover()));

        if ("1".equals(cancelUnpaidOrders)) {
            Long cancelUnpaidOrdersTimes = Long.parseLong(cancelUnpaidOrdersTimesStr);
            Long orderExpireTime = createTime * 1000 + cancelUnpaidOrdersTimes * 60 * 1000;
            vo.setCancelUnpaidOrders(true);
            vo.setOrderExpireTime(orderExpireTime);
        } else {
            vo.setCancelUnpaidOrders(false);
            vo.setOrderExpireTime(0l);
        }

        if (vo.getOrderStatus().intValue() != OrderEnum.ORDER_STATUS_COMPLETED.getCode()) {
            vo.setShowComment(false);
        } else if (vo.getRefundStatus().intValue() != OrderEnum.REFUND_STATUS_NO.getCode()) {
            vo.setShowComment(false);
        } else {
            vo.setShowComment(!vo.isCommented());
        }


        CouponReceive model = couponReceiveMapper.selectOne(
                new QueryWrapper<CouponReceive>()
                        .eq("used_order_id", id)
                        .eq("user_id", userId)
                        .last("limit 1"));

        if (model != null) {
            Integer couponId = model.getCouponId();
            CouponReceive usedCouponReceive = couponReceiveMapper.selectOne(
                    new QueryWrapper<CouponReceive>()
                            .eq("coupon_id", couponId)
                            .eq("status", 1)
                            .last("limit 1"));
            vo.setUsedCoupon(usedCouponReceive != null);
            vo.setCouponDiscountPrice(usedCouponReceive != null ? vo.getCouponDiscountPrice() : new BigDecimal("0"));
        }

        return vo;
    }

    @Override
    public Order getById(Integer id) {
        return orderMapper.selectById(id);
    }

    @Override
    public Order updateSn(Integer id) {
       Order order = orderMapper.selectById(id);
       org.springframework.util.Assert.notNull(order, "订单不存在");
       order.setSn(randMakeOrderSn());
       order.setPayWay(OrderEnum.ORDER_PAY_WAY_WX.getCode());
       this.orderMapper.updateById(order);
       return order;
    }

    /**
     * 订单新增
     *
     * @author panweiliang
     * @param orderParam 参数
     */
    @Override
    public OrderDetailVo add(OrderParam orderParam) {

        String cancelUnpaidOrders = LsConfigUtil.get("transaction", "cancel_unpaid_orders");

        String cancelUnpaidOrdersTimesStr = LsConfigUtil.get("transaction", "cancel_unpaid_orders_times", "30");

        Integer userId = orderParam.getUserId();
        Integer courseId = orderParam.getCourseId();
        BigDecimal couponDiscountPrice = new BigDecimal("0");
        BigDecimal integralDiscountPrice = new BigDecimal("0");

//        couponDiscountPrice = couponDiscountPrice != null ? couponDiscountPrice : new BigDecimal("0");
//        integralDiscountPrice = integralDiscountPrice != null ? integralDiscountPrice : new BigDecimal("0");

        //判断当前课程是否存在
        Course course = courseMapper.selectOne(
                new QueryWrapper<Course>()
                        .eq("id", courseId)
                        .last("limit 1"));
        Assert.notNull(course, "课程数据不存在");

        Assert.isTrue(course.getFeeType().intValue() == 1, "当前课程为免费课程，可直接加入");

        //需要先判断当前用户是否已经下当前课程的订单。
        MPJQueryWrapper<Order> mpjQueryWrapper = new MPJQueryWrapper<Order>()
                .selectAll(Order.class)
                .innerJoin("?_order_course oc ON oc.order_id=t.id".replace("?_", GlobalConfig.knowledgePaymentTablePrefixe))
                .eq("oc.course_id", courseId)
                .eq("t.user_id", userId)
                .eq("t.order_status", OrderEnum.ORDER_STATUS_COMPLETED.getCode())
                .eq("t.refund_status", OrderEnum.REFUND_STATUS_NO)
//                .nested(wq->wq
//                        .eq("refund_status", OrderEnum.REFUND_STATUS_NO).or()
//                        .eq("refund_status", OrderEnum.REFUND_STATUS_FULL))
                .isNull("t.delete_time")
                .last("limit 1");

        Order order = orderMapper.selectJoinOne(Order.class, mpjQueryWrapper);
        Assert.isNull(order, "当前课程已下过单，请不要重复下单");

        Order model = new Order();
        model.setSn(this.randMakeOrderSn());
        model.setTransactionId(null);
        model.setUserId(orderParam.getUserId());
        model.setOrderTerminal(orderParam.getOrderTerminal());
        model.setOrderStatus(OrderEnum.ORDER_STATUS_UNPAID.getCode());
        model.setPayStatus(OrderEnum.PAY_STATUS_UNPAID.getCode());
        model.setPayWay(orderParam.getPayWay());
        model.setPayTime(null);
        model.setTotalAmount(course.getSellPrice());
        BigDecimal orderAmount = course.getSellPrice().subtract(couponDiscountPrice).subtract(integralDiscountPrice);
        model.setOrderAmount(orderAmount);
        model.setCouponDiscountPrice(couponDiscountPrice);
        model.setIntegralDiscountPrice(integralDiscountPrice);
        model.setRefundStatus(OrderEnum.REFUND_STATUS_NO.getCode());
        model.setCancelTime(null);
        model.setRefundTime(null);
        model.setShopRemark("");
        model.setCreateTime(System.currentTimeMillis() / 1000);
        model.setUpdateTime(System.currentTimeMillis() / 1000);
        orderMapper.insert(model);

        OrderDetailVo orderDetailVo = new OrderDetailVo();
        BeanUtils.copyProperties(model, orderDetailVo);
        Integer orderId = model.getId();

        OrderCourse orderCourse = new OrderCourse();
        orderCourse.setOrderId(orderId);
        orderCourse.setCourseId(courseId);
        String courseSnap = JSONObject.toJSONString(course);
        orderCourse.setCourseSnap(courseSnap);
        orderCourse.setIsComment(0);

        orderCourseMapper.insert(orderCourse);
        OrderLog orderLog = new OrderLog();
        orderLog.setChannel(OrderLogEnum.CHANNEL_USER_ADD_ORDER.getCode());
        orderLog.setOrderId(orderId);
        orderLog.setContent(OrderLogEnum.CHANNEL_USER_ADD_ORDER.getMsg());
        orderLog.setType(OrderLogEnum.TYPE_SELLER.getCode());
        orderLog.setOperatorId(userId);
        orderLog.setCreateTime(TimeUtil.timestamp());
        orderLog.setUpdateTime(TimeUtil.timestamp());

        orderLogMapper.insert(orderLog);
        if ("1".equals(cancelUnpaidOrders)) {
            Long cancelUnpaidOrdersTimes = Long.parseLong(cancelUnpaidOrdersTimesStr);
            Long orderExpireTime = model.getUpdateTime() * 1000 + cancelUnpaidOrdersTimes * 60 * 1000;
            orderDetailVo.setCancelUnpaidOrders(true);
            orderDetailVo.setOrderExpireTime(orderExpireTime);
        } else {
            orderDetailVo.setCancelUnpaidOrders(false);
            orderDetailVo.setOrderExpireTime(0l);
        }

        orderDetailVo.setCreateTime(TimeUtil.timestampToDate(model.getCreateTime()));
        orderDetailVo.setCourseSnap(courseSnap);
        orderDetailVo.setCourseCover(UrlUtil.toAbsoluteUrl(course.getCover()));
        orderDetailVo.setCourseName(course.getName());
        orderDetailVo.setCourseSellPrice(course.getSellPrice());
        orderDetailVo.setCouponDiscountPrice(couponDiscountPrice);
        orderDetailVo.setIntegralDiscountPrice(integralDiscountPrice);

        return orderDetailVo;
    }

    /**
     * 生成唯一订单号
     *
     * @author panweiliang
     * @return Integer
     */
    private String randMakeOrderSn() {
        String sn;
        while (true) {
            sn = ToolsUtil.randomDigitString(18);
            Order snModel = orderMapper.selectOne(new QueryWrapper<Order>()
                    .select("id")
                    .eq("sn", sn)
                    .last("limit 1"));
            if (snModel == null) {
                break;
            }
        }
        return sn;
    }

    @Override
    public boolean updateOrderPayStatusToPaid(Integer orderId) throws WxPayException {
        Order order = this.orderMapper.selectById(orderId);
        Assert.notNull(order, "订单数据不存在");
        return this.updateOrderStatusToPaid(order.getSn(), null);
    }
    @Override
    public boolean updateOrderStatusToPaid(String outTradeNo, String transactionId) throws WxPayException {

        String enable = LsConfigUtil.get("consumption_reward", "enable", "1");
        String rewardMethod = LsConfigUtil.get("consumption_reward", "reward_method", "1");
        String event = LsConfigUtil.get("consumption_reward", "event", "0");
        String integralMethod = LsConfigUtil.get("consumption_reward", "integral_method", "0");
        String integralValue = LsConfigUtil.get("consumption_reward", "integral_value", "0");

        Order order = this.orderMapper.selectOne(
                new QueryWrapper<Order>()
                        .eq("sn", outTradeNo)
                        .last("limit 1"));

        OrderCourse orderCourse = this.orderCourseMapper.selectOne(
                new QueryWrapper<OrderCourse>()
                        .eq("order_id", order.getId())
                        .last("limit 1"));
        Assert.notNull(orderCourse, "订单未关联课程");

        Course course = this.courseMapper.selectOne(
                new QueryWrapper<Course>()
                        .eq("id", orderCourse.getCourseId())
                        .last("limit 1"));

        Assert.notNull(orderCourse, "订单关联的课程不存在");

        Integer userId = order.getUserId();
        User user = userMapper.selectById(userId);

        if (order != null && OrderEnum.PAY_STATUS_UNPAID.getCode() == order.getPayStatus().intValue()) {
            WxPayService wxService = WxPayServiceUtil.handler(String.valueOf(ClientEnum.MNP.getCode()));
            WxPayOrderQueryV3Result wxPayOrderQueryV3Result = wxService.queryOrderV3(transactionId, outTradeNo);
            String tradeState = wxPayOrderQueryV3Result.getTradeState();
            log.info("支付订单状态:" + tradeState);
            transactionId = wxPayOrderQueryV3Result.getTransactionId();


            Integer orderId = order.getId();
            CouponReceive couponReceive = couponReceiveMapper.selectOne(
                    new QueryWrapper<CouponReceive>()
                            .eq("used_order_id", orderId)
                            .last("limit 1"));


            if ("SUCCESS".equals(tradeState)) {
                StudyCourse studyCourse = studyCourseMapper.selectOne(
                        new QueryWrapper<StudyCourse>()
                                .eq("course_id", orderCourse.getCourseId())
                                .eq("user_id", userId)
                                .isNull("delete_time")
                                .last("limit 1"));
                if(studyCourse == null) {
                    order.setTransactionId(transactionId);
                    order.setOrderStatus(OrderEnum.ORDER_STATUS_COMPLETED.getCode());
                    order.setPayStatus(OrderEnum.PAY_STATUS_PAID.getCode());
                    order.setUpdateTime(TimeUtil.timestamp());
                    order.setPayTime(TimeUtil.timestamp());
                    OrderLog orderLog = new OrderLog();
                    orderLog.setChannel(OrderLogEnum.CHANNEL_USER_PAID_ORDER.getCode());
                    orderLog.setOrderId(orderId);
                    orderLog.setContent(OrderLogEnum.CHANNEL_USER_PAID_ORDER.getMsg());
                    orderLog.setType(OrderLogEnum.TYPE_SELLER.getCode());
                    orderLog.setOperatorId(userId);
                    orderLog.setCreateTime(TimeUtil.timestamp());
                    orderLog.setUpdateTime(TimeUtil.timestamp());
                    this.orderLogMapper.insert(orderLog);
                    this.orderMapper.updateById(order);
                    studyCourse = new StudyCourse();
                    studyCourse.setCourseId(orderCourse.getCourseId());
                    studyCourse.setUserId(userId);
                    studyCourse.setSourceId(orderId);
                    studyCourse.setStatus(1);
                    studyCourse.setCreateTime(TimeUtil.timestamp());
                    studyCourse.setUpdateTime(TimeUtil.timestamp());
                    this.studyCourseMapper.insert(studyCourse);
                    Integer studyNum = course.getStudyNum() != null ? course.getStudyNum() + 1 : 1;
                    course.setStudyNum(studyNum);
                    this.courseMapper.updateById(course);
                    BigDecimal orderAmount = order.getOrderAmount();
                    orderAmount = orderAmount != null ? orderAmount : new BigDecimal("0");
                    BigDecimal totalOrderAmount = user.getTotalOrderAmount();
                    Long totalOrderNum = user.getTotalOrderNum();
                    totalOrderAmount = totalOrderAmount != null ? totalOrderAmount : new BigDecimal("0");
                    totalOrderNum = totalOrderNum != null ? totalOrderNum : 0l;
                    totalOrderAmount = totalOrderAmount.add(orderAmount);
                    totalOrderNum = totalOrderNum + 1;
                    user.setTotalOrderAmount(totalOrderAmount);
                    user.setTotalOrderNum(totalOrderNum);
                    this.userMapper.updateById(user);

                    couponReceive.setStatus(1);
                    couponReceive.setUsedTime(TimeUtil.timestamp());
                    this.couponReceiveMapper.updateById(couponReceive);

                    Integer couponId = couponReceive.getCouponId();
                    Coupon coupon = this.couponMapper.selectById(couponId);
                    if (coupon != null) {
                        Integer usedCount = coupon.getUsedCount();
                        usedCount = usedCount != null ? usedCount : 0;
                        usedCount = usedCount + 1;
                        coupon.setUsedCount(usedCount);
                        this.couponMapper.updateById(coupon);
                    }

                    BigDecimal userPoints = user.getUserPoints();
                    //奖励积分
                    if ("1".equals(enable) && "1".equals(event) && "1".equals(rewardMethod)) {
                        BigDecimal rewardVal = new BigDecimal("0");
                        if ("1".equals(integralMethod)) {
                            //直接赠送
                            rewardVal = new BigDecimal(integralValue);
                        } else {
                            //按比例赠送
                            rewardVal = orderAmount.multiply(new BigDecimal("0.01")).multiply(new BigDecimal(integralValue));
                        }
                        ConsumptionIncentives consumptionIncentives = new ConsumptionIncentives();
                        consumptionIncentives.setOrderId(orderId);
                        consumptionIncentives.setRewardType(Integer.valueOf(rewardMethod));
                        consumptionIncentives.setRewardContent(rewardVal.toString());
                        consumptionIncentives.setUserId(userId);
                        consumptionIncentives.setUpdateTime(TimeUtil.timestamp());
                        consumptionIncentives.setCreateTime(TimeUtil.timestamp());
                        this.consumptionIncentivesMapper.insert(consumptionIncentives);

                        userPoints = userPoints.add(rewardVal);
                        user.setUserPoints(userPoints);
                        this.userMapper.updateById(user);

                        PointsLog pointsLog = new PointsLog();
                        pointsLog.setUserId(userId);
                        pointsLog.setChangePoints(rewardVal);
                        pointsLog.setChangeType(PointsChangeEnum.BNW_INC_ORDER.getCode());
                        pointsLog.setRemark("消费赠送积分");
                        pointsLog.setLeftPoints(userPoints);
                        pointsLog.setAction(PointsChangeEnum.ACTION_INC.getCode());
                        pointsLog.setAssociationSn(order.getSn());
                        pointsLog.setCreateTime(TimeUtil.timestamp());
                        pointsLog.setUpdateTime(TimeUtil.timestamp());
                        this.pointsLogMapper.insert(pointsLog);
                    }

                    BigDecimal integralDiscountPrice = order.getIntegralDiscountPrice();
                    if (integralDiscountPrice != null && integralDiscountPrice.compareTo(BigDecimal.ZERO) == 1) {
//                        String scaleStr = LsConfigUtil.get("point_deduction", "scale", "10");
//                        BigDecimal scale = new BigDecimal(scaleStr);
                        BigDecimal deductVal = order.getIntegralVal();
                        deductVal = deductVal.setScale(0, BigDecimal.ROUND_UP);
                        userPoints = userPoints.subtract(deductVal);
                        PointsLog pointsLog = new PointsLog();
                        pointsLog.setUserId(userId);
                        pointsLog.setChangePoints(deductVal);
                        pointsLog.setChangeType(PointsChangeEnum.BNW_DEC_ORDER.getCode());
                        pointsLog.setRemark("消费扣减积分");
                        pointsLog.setLeftPoints(userPoints);
                        pointsLog.setAction(PointsChangeEnum.ACTION_DEC.getCode());
                        pointsLog.setAssociationSn(order.getSn());
                        pointsLog.setCreateTime(TimeUtil.timestamp());
                        pointsLog.setUpdateTime(TimeUtil.timestamp());
                        this.pointsLogMapper.insert(pointsLog);
                    }
                }
                return true;
            } else {
                couponReceive.setStatus(0);
                couponReceive.setUsedOrderId(null);
                couponReceive.setUsedTime(null);
                this.couponReceiveMapper.updateById(couponReceive);
            }
        }
        return false;
    }

    /**
     * 取消订单
     *
     * @author panweiliang
     * @param id 主键ID
     */
    @Override
    public void cancel(Integer id) {
        Integer userId = LikeFrontThreadLocal.getUserId();
        Order model = orderMapper.selectOne(
                new QueryWrapper<Order>()
                        .eq("id", id)
                        .eq("user_id", userId)
                        .last("limit 1"));

        org.springframework.util.Assert.notNull(model, "订单数据不存在!");
        org.springframework.util.Assert.isTrue(model.getOrderStatus().intValue() == OrderEnum.ORDER_STATUS_UNPAID.getCode(), "订单非待付款状态，无法取消");
        model.setCancelTime(TimeUtil.timestamp());
        model.setOrderStatus(OrderEnum.ORDER_STATUS_CLOSED.getCode());
        this.orderMapper.updateById(model);
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(model.getId());
        orderLog.setContent(OrderLogEnum.CHANNEL_USER_CANCEL_ORDER.getMsg());
        orderLog.setChannel(OrderLogEnum.CHANNEL_USER_CANCEL_ORDER.getCode());
        orderLog.setOperatorId(userId);
        orderLog.setType(OrderLogEnum.TYPE_SELLER.getCode());
        orderLog.setUpdateTime(TimeUtil.timestamp());
        orderLog.setCreateTime(TimeUtil.timestamp());
        orderLogMapper.insert(orderLog);
    }

    /**
     * 订单删除
     *
     * @author panweiliang
     * @param id 主键ID
     */
    @Override
    public void del(Integer id) {
        Order model = orderMapper.selectOne(
                new QueryWrapper<Order>()
                        .eq("id", id)
                        .last("limit 1"));

        org.springframework.util.Assert.notNull(model, "订单数据不存在!");
        org.springframework.util.Assert.isTrue(model.getOrderStatus().intValue() == OrderEnum.ORDER_STATUS_CLOSED.getCode(), "订单未关闭状态，无法删除");
        model.setDeleteTime(TimeUtil.timestamp());
        this.orderMapper.updateById(model);
    }
}
